package com.javaweb.servlet;


import com.adminx.utils.ModelAndView;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * LoginServlet for login request.
 * there are two ways for configuring servlet
 *  A. in web.xml
 *  B. @WebServlet
 */

@WebServlet( "/test/nativeAjax")
public class NativeAjaxServlet extends HttpServlet {
    private Logger logger = LogManager.getLogger(NativeAjaxServlet.class) ;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp) ;
    }
    /**
     * override doPost logic from father by our own business logic
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * process the arrived request in following logic.
         * At FIRST: SETTING ENCODING.
         */
       req.setCharacterEncoding("utf-8");
       String methodType = req.getMethod() ;
       String action = null ;
        String requestString = null ;
        Map<String, Object> requestData = null ;
       // for post
       if (methodType.equalsIgnoreCase("POST")) {
           // for native post
           //action = this.getRequestParameter(requestString, 0);
           // for native post in json
           // parse json string to a map
            requestData = getRequestData(req, Map.class) ;
            action = (String) requestData.get("action") ;

       } else {
           // for get
           action = req.getParameter("action");
       }
        logger.debug("do action: {} ", action)  ;
        switch (action) {
            case "selectCity":
                selectCity(req, resp);
                break ;
            case "doRate":
                doRate(req, resp, requestString) ;
                break;
            case "doRateByJSON":
                doRateByJSON(req, resp, requestData) ;
                break ;
        }


    }
    private void selectCity(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String nationId = req.getParameter("nationId") ;
        logger.debug("get city for parameter: {} ", nationId)  ;
        String cityStr = "" ;
        switch (nationId) {
            case "1":
                cityStr = "北京|上海|广东|深圳|西安|杭州";
                break;
            case "2":
                cityStr = "NewYork|Washington|LosAngles|Chicago";
                break;
            case "3":
                cityStr = "东京|大阪|横滨|名古屋";
                break;
        }
        resp.setContentType("application/text;charset=utf-8");
        PrintWriter out = resp.getWriter() ;
        out.print(cityStr) ;
        out.flush() ;

    }

    private void doRateByJSON(HttpServletRequest req, HttpServletResponse resp, Map<String, Object> requestData) throws ServletException, IOException {
        logger.debug("do rating: ")  ;
        String ratingValue = (String) requestData.get("ratingValue") ;
        String comment =   (String) requestData.get("comment") ;
        logger.debug("paramters: {} {}. ", ratingValue, comment) ;
        ModelAndView retData = ModelAndView.buildSuccess(resp) ;
        retData.addAttribute("ratingValue", ratingValue)
                .addAttribute("comment", comment) ;
        retData.response();

    }

    private void doRate(HttpServletRequest req, HttpServletResponse resp, String requestString) throws ServletException, IOException {
        logger.debug("do rating: ")  ;
        String ratingValue = this.getRequestParameter(requestString, 1) ;
        String comment =  this.getRequestParameter(requestString, 2)  ;
        resp.setContentType("application/text;charset=utf-8");
        PrintWriter out = resp.getWriter() ;
        out.print(ratingValue + "&" + comment) ;
        out.flush() ;
    }

    private String readRequestString(HttpServletRequest request)throws IOException {

        // 先将 string 读出来
        BufferedReader br = request.getReader();
        String line = null;
        StringBuilder jsonBuffer = new StringBuilder();
        while ((line = br.readLine()) != null) {
            jsonBuffer.append(line);
        }
        return jsonBuffer.toString();
    }

    private String getRequestParameter(String requestString, int index) {
        String tokens[] = requestString.split("&") ;
        if (tokens == null || index >= tokens.length) {
            return null ;
        }
        return tokens[index] ;

    }

    /**
     * only for native post request
     * @param req
     * @param clazz
     * @param <T>
     * @return
     */

    public static <T> T getRequestData(HttpServletRequest req, Class<T> clazz) {
        // part 1. read paramter string from request
        StringBuilder stringBuilder = new StringBuilder() ;
        // the jackson mapper: serialized and parsing
        ObjectMapper mapper = new ObjectMapper() ;
        String line = null ;
        try (BufferedReader reader = req.getReader()) {
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line) ;
            }
            return mapper.readValue(stringBuilder.toString(), clazz) ;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null ;
    }




}





